package fabu

import (
	hdmap "camap/modules/map/proto"
	"encoding/xml"
	"math"
	"strconv"
	"strings"

	log "github.com/sirupsen/logrus"

	"github.com/twpayne/go-geom"
	"github.com/twpayne/go-geom/xy"
)

type HdRoadMap map[string]*hdmap.Road
type HdLaneMap map[string]*hdmap.Lane
type HdRoad hdmap.Road
type HdLane hdmap.Lane

var ROADS = make(HdRoadMap)
var LANES = make(HdLaneMap)

var ndsList = []Node{}
var extraPtsList = []ExtraPoints{}
var pavesList = []Pavement{}
var consList = []Connection{}
var sectsList = []Section{}
var lmarksList = []Lanemarker{}
var redgsList = []RoadEdge{}

func MakeFabuXML(xmap *hdmap.Map) []byte {
	if xmap == nil {
		return nil
	}
	Pretreatment(xmap)
	//先处理路口,使用pncjunction,方便获取道路的路口进出关系
	for _, j := range xmap.PncJunction {

		center := PolygonCentroid(j.Polygon)
		//nodes
		nds := []Nd{}
		for _, pt := range j.Polygon.Point {
			nId := strconv.Itoa(len(ndsList))
			//make node
			ndsList = append(ndsList, Node{
				ID:   nId,
				UtmX: strconv.FormatFloat(*pt.X, 'f', -1, 64),
				UtmY: strconv.FormatFloat(*pt.Y, 'f', -1, 64),
				UtmZ: strconv.FormatFloat(*pt.Z, 'f', -1, 64),
			})
			//make ndref
			nds = append(nds, Nd{
				Ref: nId,
			})
		}
		//extrapoints
		extraId := strconv.Itoa(len(extraPtsList)) //id
		extraPtsList = append(extraPtsList, ExtraPoints{
			ID:  extraId,
			Nds: nds,
		})
		//make extraref
		extraRef := ExtraPointsRef{
			Ref: extraId,
		}
		//Pavements
		cwIds := make(map[string]string)
		//查找crosswalk的overlapids
		for _, ol := range j.GetOverlapId() {
			id := ol.GetId()
			if strings.Contains(id, "_CrossWalk") {
				pos := strings.Index(id, "_CrossWalk")
				cwId := id[pos+10:]
				cwIds[cwId] = id
			}
		}

		//处理crosswalk,构造lines&nodes,并记录refs
		paveRefs := []PavementRef{}
		for _, cw := range xmap.Crosswalk {
			cwId := cw.Id.GetId()
			_, in := cwIds[cwId]
			if !in {
				continue
			}
			cwpoly := cw.GetPolygon()
			if cwpoly == nil {
				continue
			}
			lines := GetCrossWalkLines(cwpoly)
			pavesList = append(pavesList, Pavement{
				ID:    cwId,
				Lines: lines,
			})
			//make pavRefs
			paveRefs = append(paveRefs, PavementRef{
				Ref: cwId,
			})
		}

		//ExitPairs,from→to
		exitPairs := []ExitPair{}
		for _, g := range j.PassageGroup {
			gId := g.Id.GetId()
			pos := strings.Index(gId, "_Link")
			linkId := gId[pos+5:]
			// log.Infof("passage group id:%s, linkpid:%s", gId, linkId)
			//正常情况下passage就一个，进一步找passage里面的进入车道
			for _, p := range g.Passage {
				//from
				if *p.Type.Enum() == *hdmap.Passage_ENTRANCE.Enum() {
					//repeat lanes
					for _, g2 := range j.PassageGroup {
						gId2 := g2.Id.GetId()
						pos2 := strings.Index(gId2, "_Link")
						linkId2 := gId2[pos2+5:]
						// log.Infof("passage group id:%s, link id:%s", gId2, linkId2)
						for _, p2 := range g2.Passage {
							//to
							if *p2.Type.Enum() == *hdmap.Passage_EXIT.Enum() {
								//create pairs
								t := QueryExitPairType(p.LaneId, linkId2)
								if t == -1 {
									continue //说明类型不对（不通），则不构造pairs
								}
								exitPair := ExitPair{
									From: linkId,
									To:   linkId2,
									Type: strconv.Itoa(t),
								}
								exitPairs = append(exitPairs, exitPair)
							}
						}
					}
				}
			}
		}

		conn := Connection{
			ID:             j.Id.GetId(),
			Center:         center,
			ExtraPointsRef: extraRef,
			PavementRefs:   paveRefs,
			ExitPairs:      exitPairs,
			ConnectionType: ConnectionType{
				Type: "1",
			},
		}
		consList = append(consList, conn)
	}

	//处理道路section
	for _, r := range xmap.Road {
		if len(r.Section) == 0 {
			continue
		}
		lids := r.GetSection()[0].GetLaneId()
		lanes := []Lane{}
		for _, lid := range lids {
			id := lid.GetId()
			hdl, ok := LANES[id]
			if ok {
				tfl := TrafficLight{
					ID:   "",
					UtmX: "",
					UtmY: "",
					UtmZ: "",
					Signals: []Signal{
						Signal{
							Type: "", //0 圆灯 1 直⾏ 2 左转 4 右转 8掉头 10掉头左转 5直⾏右转
						},
					},
					Type: TrafficLightType{
						Value: "",
					},
					CountdownNumberWidth: CountdownNumberWidth{
						Value: "0", //倒计时数字的位数（0：⽆倒计时，1：⼀位数倒计时，2：两位数倒计时
					},
					IsWaitingAreaLight: IsWaitingAreaLight{
						Value: "0", //是否对应待⾏区（0：否；1：是)
					},
					IsInvalidSignal: IsInvalidSignal{
						Value: "0", //该红绿灯坐标是否精准（0：否，1：是)
					},
				}
				leftMarkType := Hd2MarkType(hdl.LeftBoundary.GetBoundaryType())
				lineLeft := hdl.LeftBoundary.Curve.Segment[0].GetLineSegment().GetPoint()
				nds1 := []Nd{}
				for _, pt := range lineLeft {
					nId := strconv.Itoa(len(ndsList))
					nd := Node{
						ID:   nId,
						UtmX: strconv.FormatFloat(*pt.X, 'f', -1, 64),
						UtmY: strconv.FormatFloat(*pt.Y, 'f', -1, 64),
						UtmZ: strconv.FormatFloat(*pt.Z, 'f', -1, 64),
					}
					ndsList = append(ndsList, nd)
					nds1 = append(nds1, Nd{
						Ref: nId,
					})
				}
				leftId := "Left" + hdl.Id.GetId()
				left := Lanemarker{
					ID:   leftId,
					Type: strconv.Itoa(leftMarkType),
					Nds:  nds1,
				}
				lmarksList = append(lmarksList, left)
				rightMarkType := Hd2MarkType(hdl.LeftBoundary.GetBoundaryType())
				nds2 := []Nd{}
				lineRight := hdl.RightBoundary.Curve.Segment[0].GetLineSegment().GetPoint()
				for _, pt := range lineRight {
					nId := strconv.Itoa(len(ndsList))
					nd := Node{
						ID:   nId,
						UtmX: strconv.FormatFloat(*pt.X, 'f', -1, 64),
						UtmY: strconv.FormatFloat(*pt.Y, 'f', -1, 64),
						UtmZ: strconv.FormatFloat(*pt.Z, 'f', -1, 64),
					}
					ndsList = append(ndsList, nd)
					nds2 = append(nds2, Nd{
						Ref: nId,
					})
				}
				rightId := "Right" + hdl.Id.GetId()
				right := Lanemarker{
					ID:   rightId,
					Type: strconv.Itoa(rightMarkType),
					Nds:  nds2,
				}
				lmarksList = append(lmarksList, right)

				laneType := Hd2LaneType(hdl.Type)
				laneTurn := Hd2LaneTurn(hdl.Turn)
				lane := Lane{
					ID: id,
					Type: LaneType{
						Val: strconv.Itoa(laneType),
					},
					TurnType: TurnType{
						Val: strconv.Itoa(laneTurn),
					},
					LeftLanemarker: LanemarkerRef{
						Ref: leftId,
					},
					RightLanemarker: LanemarkerRef{
						Ref: rightId,
					},
					LaneSpeedLimits: LaneSpeedLimits{
						Min: "0",
						Max: strconv.FormatFloat(hdl.GetSpeedLimit(), 'f', -1, 64),
					},
					TrafficLight: tfl,
				}
				lanes = append(lanes, lane)
			}
		}

		enter := Enter{
			Left:  "",
			Right: "",
		}
		enterLeft, enterRight := GetRoadEnter(r.GetSection()[0].Boundary)
		if enterLeft != nil {
			nId := strconv.Itoa(len(ndsList))
			//make node
			ndsList = append(ndsList, Node{
				ID:   nId,
				UtmX: strconv.FormatFloat(*enterLeft.X, 'f', -1, 64),
				UtmY: strconv.FormatFloat(*enterLeft.Y, 'f', -1, 64),
				UtmZ: strconv.FormatFloat(*enterLeft.Z, 'f', -1, 64),
			})
			enter.Left = nId
		}
		if enterRight != nil {
			nId := strconv.Itoa(len(ndsList))
			//make node
			ndsList = append(ndsList, Node{
				ID:   nId,
				UtmX: strconv.FormatFloat(*enterLeft.X, 'f', -1, 64),
				UtmY: strconv.FormatFloat(*enterLeft.Y, 'f', -1, 64),
				UtmZ: strconv.FormatFloat(*enterLeft.Z, 'f', -1, 64),
			})
			enter.Right = nId
		}

		secType := Hd2RoadType(r.Type)
		sect := Section{
			ID:   r.Id.GetId(),
			From: r.JunctionId.GetId(),
			To:   r.JunctionId.GetId(),
			SectionType: SectionType{
				Type: strconv.Itoa(secType),
			},
			Lane: lanes,
			IsReversible: IsReversible{
				Value: "0",
			},
			IsBidirectional: IsBidirectional{
				Value: "0",
			},
			IsRamp: IsRamp{
				Value: "0",
			},
			Enter: enter,
		}
		sectsList = append(sectsList, sect)

		edgeLeft, edgeRight := GetRoadEdge(r.GetSection()[0].Boundary)
		if edgeLeft != nil {

			nds := []Nd{}
			for _, pt := range edgeLeft.Point {
				nId := strconv.Itoa(len(ndsList))
				//make node
				ndsList = append(ndsList, Node{
					ID:   nId,
					UtmX: strconv.FormatFloat(*pt.X, 'f', -1, 64),
					UtmY: strconv.FormatFloat(*pt.Y, 'f', -1, 64),
					UtmZ: strconv.FormatFloat(*pt.Z, 'f', -1, 64),
				})
				nds = append(nds, Nd{
					Ref: nId,
				})
			}

			redge := RoadEdge{
				ID:         r.Id.GetId() + "LeftEdge",
				AcrossType: "1",
				Type:       "5",
				Nds:        nds,
			}

			redgsList = append(redgsList, redge)
		}
		if edgeRight != nil {
			nds := []Nd{}

			for _, pt := range edgeRight.Point {

				nId := strconv.Itoa(len(ndsList))
				//make node
				ndsList = append(ndsList, Node{
					ID:   nId,
					UtmX: strconv.FormatFloat(*pt.X, 'f', -1, 64),
					UtmY: strconv.FormatFloat(*pt.Y, 'f', -1, 64),
					UtmZ: strconv.FormatFloat(*pt.Z, 'f', -1, 64),
				})
				nds = append(nds, Nd{
					Ref: nId,
				})
			}

			redge := RoadEdge{
				ID:         r.Id.GetId() + "RightEdge",
				AcrossType: "1",
				Type:       "5",
				Nds:        nds,
			}

			redgsList = append(redgsList, redge)
		}
	}

	m := &Map{
		ID:          "10101",
		ExtraPoints: extraPtsList,
		Pavements:   pavesList,
		Connections: consList,
		Sections:    sectsList,
		Lanemarkers: lmarksList,
		RoadEdges:   redgsList,
		Nodes:       ndsList,
	}

	output, err := xml.MarshalIndent(m, "  ", "    ")
	if err != nil {
		log.Errorf("marshal xml error, details: %s", err)
	}
	return output
}

func PolygonCentroid(polyin *hdmap.Polygon) Center {
	if polyin == nil {
		return Center{}
	}

	flatCoords := []float64{}
	for _, pt := range polyin.Point {
		flatCoords = append(flatCoords, []float64{*pt.X, *pt.Y, *pt.Z}...)
	}
	poly := geom.NewPolygonFlat(geom.XYZ, flatCoords, []int{len(flatCoords)})

	ct, err := xy.Centroid(poly)
	if err != nil {
		log.Error(err)
		return Center{}
	}

	return Center{
		UtmX: strconv.FormatFloat(ct.X(), 'f', -1, 64),
		UtmY: strconv.FormatFloat(ct.Y(), 'f', -1, 64),
		UtmZ: strconv.FormatFloat(*polyin.Point[0].Z, 'f', -1, 64),
	}
}

func GetCrossWalkLines(cwpoly *hdmap.Polygon) []Line {
	lines := []Line{} //①makelines,找到crosswalk的overlap,找到polygon,构造两条线

	dist1, dist2 := 0.0, 0.0
	i1, i2 := 0, 0
	for i := 0; i < len(cwpoly.Point)-1; i++ {
		dist := Distance(cwpoly.Point[i], cwpoly.Point[i+1])
		if dist1 < dist {
			dist2 = dist1
			i2 = i1
			if i == 0 {
				dist2 = dist
				i2 = i1
			}
			dist1 = dist
			i1 = i
		} else {
			//若第一个就是最大,则持续找第二大
			if dist2 >= dist1 {
				dist2 = dist
			}
			if dist2 < dist {
				dist2 = dist
				i2 = i1
			}
		}
	}
	// fmt.Printf("dist1:%f~Point[%d],dist2:%f~Point[%d] ~\n", dist1, i1, dist2, i2)

	//暂时取长边组织line
	l1 := MakeLine(cwpoly.Point[i1], cwpoly.Point[i1+1])
	// fmt.Printf("%v,%v\n", cwpoly.Point[i1], cwpoly.Point[i1+1])
	lines = append(lines, *l1)
	l2 := MakeLine(cwpoly.Point[i2], cwpoly.Point[i2+1])
	// fmt.Printf("%v,%v\n", cwpoly.Point[i2], cwpoly.Point[i2+1])
	lines = append(lines, *l2)
	return lines
}

func MakeLine(pt1, pt2 *hdmap.PointENU) *Line {
	nId1 := strconv.Itoa(len(ndsList))
	nd1 := Node{
		ID:   nId1,
		UtmX: strconv.FormatFloat(*pt1.X, 'f', -1, 64),
		UtmY: strconv.FormatFloat(*pt1.Y, 'f', -1, 64),
		UtmZ: strconv.FormatFloat(*pt1.Z, 'f', -1, 64),
	}
	ndsList = append(ndsList, nd1)
	nId2 := strconv.Itoa(len(ndsList))
	nd2 := Node{
		ID:   nId2,
		UtmX: strconv.FormatFloat(*pt2.X, 'f', -1, 64),
		UtmY: strconv.FormatFloat(*pt2.Y, 'f', -1, 64),
		UtmZ: strconv.FormatFloat(*pt2.Z, 'f', -1, 64),
	}
	ndsList = append(ndsList, nd2)

	return &Line{
		Nds: []Nd{
			Nd{
				Ref: nId1,
			},
			Nd{
				Ref: nId2,
			},
		},
	}
}

// Distance calculates the 2d distance between the two points
func Distance(pt1, pt2 *hdmap.PointENU) float64 {
	dx := pt1.GetX() - pt2.GetX()
	dy := pt1.GetY() - pt2.GetY()
	return math.Sqrt(dx*dx + dy*dy)
}

//QueryExitPairType 转向关系(0左转 1直⾏ 2右转 3掉头)→1234/直左右掉，返回-1说明没有转向关系
func QueryExitPairType(lids []*hdmap.Id, to string) int {
	//lids是路口内的连接转向关系的车道组
	//找到驶出道路，确认lids的后继车道是否属于这个使出道路，确认专线关系，构造pair
	t := -1
	hdr, ok := ROADS[to]
	if !ok {
		return t
	}

	for _, lid := range lids {
		hdl, ok := LANES[lid.GetId()]
		if ok {
			//next
			nextIds := hdl.GetSuccessorId()
			if len(nextIds) == 0 {
				continue
			}
			for _, nextId := range nextIds {
				lanes := hdr.Section[0].GetLaneId()
				for _, lane := range lanes {
					if nextId.GetId() == lane.GetId() {
						switch int(*hdl.Turn) {
						case 2:
							t = 0
						case 3:
							t = 2
						case 4:
							t = 3
						default:
							t = 1 //hdmap.Lane_NO_TURN.Enum()
						}
						return t
					}
				}
			}
		}
	}
	return t
}

//Pretreatment 预处理hdmap,优化查询速度
func Pretreatment(xmap *hdmap.Map) {
	if xmap == nil {
		return
	}
	//pre roads
	for _, r := range xmap.Road {
		ROADS[r.Id.GetId()] = r
	}

	//pre lanes
	for _, l := range xmap.Lane {
		LANES[l.Id.GetId()] = l
	}
}

//Hd2RoadType 映射roadtype, 0,1→城市道路、高速
func Hd2RoadType(rtype *hdmap.Road_Type) int {
	// 	Road_UNKNOWN   Road_Type = 0
	// 	Road_HIGHWAY   Road_Type = 1
	// 	Road_CITY_ROAD Road_Type = 2
	// 	Road_PARK      Road_Type = 3
	switch int(*rtype) {
	case 1:
		return 1
	case 2:
		return 0
	default:
		log.Errorf("road type(%d) curious ∑( 口 ||", *rtype)
	}

	return 0 //默认城市道路
}

//Hd2LaneType 映射lanetype, 0,1,2,4,5,6→机动车道、非机动车道、应急车道、公交车道、龙门吊车道、桥吊车道
func Hd2LaneType(ltype *hdmap.Lane_LaneType) int {
	// Lane_NONE         Lane_LaneType = 1
	// Lane_CITY_DRIVING Lane_LaneType = 2
	// Lane_BIKING       Lane_LaneType = 3
	// Lane_SIDEWALK     Lane_LaneType = 4
	// Lane_PARKING      Lane_LaneType = 5
	// Lane_SHOULDER     Lane_LaneType = 6
	switch int(*ltype) {
	case 2:
		return 0
	case 3:
		return 1
	default:
		log.Errorf("lane type(%d) curious ∑( 口 ||", *ltype)
	}

	return 0 //默认返回直行
}

//Hd2LaneTurn 映射turn, 0,1,2,4,8→无方向、直行、左转、右转、掉头
func Hd2LaneTurn(lturn *hdmap.Lane_LaneTurn) int {
	// Lane_NO_TURN    Lane_LaneTurn = 1
	// Lane_LEFT_TURN  Lane_LaneTurn = 2
	// Lane_RIGHT_TURN Lane_LaneTurn = 3
	// Lane_U_TURN     Lane_LaneTurn = 4
	switch int(*lturn) {
	case 1:
		return 1
	case 2:
		return 2
	case 3:
		return 4
	case 4:
		return 8
	default:
		log.Errorf("lane turn(%d) curious ∑( 口 ||", *lturn)
	}

	return 1 //默认返回直行
}

//Hd2MarkType 映射markType, 阿波罗lanemarktype是数组的数组,第一层是单线双线，第二层是每一条线的样式
func Hd2MarkType(markType []*hdmap.LaneBoundaryType) int {
	// LaneBoundaryType_UNKNOWN       LaneBoundaryType_Type = 0
	// LaneBoundaryType_DOTTED_YELLOW LaneBoundaryType_Type = 1
	// LaneBoundaryType_DOTTED_WHITE  LaneBoundaryType_Type = 2
	// LaneBoundaryType_SOLID_YELLOW  LaneBoundaryType_Type = 3
	// LaneBoundaryType_SOLID_WHITE   LaneBoundaryType_Type = 4
	// LaneBoundaryType_DOUBLE_YELLOW LaneBoundaryType_Type = 5
	// LaneBoundaryType_CURB          LaneBoundaryType_Type = 6
	// 0 ⽩虚线
	// 1 ⽩实线
	// 2 ⻩实线
	// 3 ⻩虚线
	// 4 双⽩实线
	// 5 双⽩虚线
	// 6 双⻩实线
	// 7 ⽩⾊实虚线
	// 8 ⽩⾊虚实线
	// 9 ⻩⾊实虚线
	// 10 ⻩⾊虚实线
	// 11 虚拟⻋道
	lineNum := len(markType)
	if lineNum == 0 {
		log.Warnln("无边界数据,映射为默认白实线~")
		return 1 //默认白实线
	}
onemark:
	if lineNum == 1 {
		if len(markType[0].Types) > 0 {
			if len(markType[0].Types) > 1 {
				log.Warnln("单边界多段情况,只映射第一段~")
			}
			t := markType[0].Types[0]
			switch int(t) {
			case 1:
				return 3
			case 2:
				return 0
			case 3:
				return 2
			case 4:
				return 1
			case 5:
				return 6
			case 6: //路牙,返回白实
				log.Warnln("未知路牙(CURB)单边界,映射为白实线~")
				return 1
			default: //未知类型,返回白实
				log.Warnln("未知类型(UNKNOWN)单边界,映射为白实线~")
				return 1
			}
		} else {
			log.Warnln("无边界数据,映射为默认白实线~")
			return 1 //默认白实线
		}
	} else {
		if len(markType) > 2 {
			log.Errorf("多余两条边界线，只处理2前两条~")
		}
		//第二条线为类型信息
		if len(markType[1].Types) == 0 {
			lineNum = 1
			goto onemark
		}
		if len(markType[0].Types) > 0 {
			if len(markType[0].Types) > 1 {
				log.Warnln("多边界多段情况,只映射第一段~")
			}
			t1 := markType[0].Types[0]
			t2 := markType[1].Types[0]
			switch int(t1) {
			case 1:
				if int(t2) == 3 {
					return 10 // 10 ⻩⾊虚实线
				}
				return 3 // 3 ⻩虚线
			case 2:
				if int(t2) == 2 {
					return 5 // 5 双⽩虚线
				} else if int(t2) == 4 {
					return 8 // 8 ⽩⾊虚实线
				}
				return 0 //白虚
			case 3:
				if int(t2) == 3 {
					return 6 // 6 双⻩实线
				} else if int(t2) == 1 {
					return 9 // 9 ⻩⾊实虚线
				}
				return 2 //黄实线
			case 4:
				if int(t2) == 4 {
					return 4 //  4 双⽩实线
				} else if int(t2) == 2 {
					return 7 //  7 ⽩⾊实虚线
				}
				return 1 //⽩实
			case 5:
				return 6
			case 6: //路牙,返回白实
				log.Warnln("未知路牙(CURB)多边界,映射为白实线~")
				return 4 //  4 双⽩实线
			default: //未知类型,返回白实
				log.Warnln("未知类型(UNKNOWN)多边界,映射为白实线~")
				return 4
			}
		}
	}
	return 1 //默认白实线
}

func GetRoadEnter(boundary *hdmap.RoadBoundary) (left, right *hdmap.PointENU) {
	if boundary != nil {
		if boundary.OuterPolygon != nil {
			if len(boundary.OuterPolygon.Edge) > 1 {
				e1 := boundary.OuterPolygon.Edge[0]
				if e1.Curve != nil {
					if len(e1.Curve.Segment) > 0 {
						if int(*e1.Type) == 2 {
							left = e1.Curve.Segment[0].StartPosition
						}
						if int(*e1.Type) == 3 {
							right = e1.Curve.Segment[0].StartPosition
						}
					}
				}
				e2 := boundary.OuterPolygon.Edge[1]
				if e2.Curve != nil {
					if len(e2.Curve.Segment) > 0 {
						if int(*e2.Type) == 2 {
							left = e2.Curve.Segment[0].StartPosition
						}
						if int(*e2.Type) == 3 {
							right = e2.Curve.Segment[0].StartPosition
						}
					}
				}
			}
		}
	}

	return left, right
}

func GetRoadEdge(boundary *hdmap.RoadBoundary) (left, right *hdmap.LineSegment) {
	if boundary != nil {
		if boundary.OuterPolygon != nil {
			if len(boundary.OuterPolygon.Edge) > 1 {
				e1 := boundary.OuterPolygon.Edge[0]
				if e1.Curve != nil {
					if len(e1.Curve.Segment) > 0 {
						if int(*e1.Type) == 2 {
							left = e1.Curve.Segment[0].GetLineSegment()
						}
						if int(*e1.Type) == 3 {
							right = e1.Curve.Segment[0].GetLineSegment()
						}
					}
				}
				e2 := boundary.OuterPolygon.Edge[1]
				if e2.Curve != nil {
					if len(e2.Curve.Segment) > 0 {
						if int(*e2.Type) == 2 {
							left = e2.Curve.Segment[0].GetLineSegment()
						}
						if int(*e2.Type) == 3 {
							right = e2.Curve.Segment[0].GetLineSegment()
						}
					}
				}
			}
		}
	}

	return left, right
}
